package com.isoftstone.disk.mybatis;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

public class TableToJavaBean
{

    private static final String LINE = "\r\n";

    private static final String TAB = "\t";

    String packages = this.getClass().getPackage().getName().replace("common", "model") + ".entity";;

    private static Map<String, String> map;

    static
    {
        map = new HashMap<String, String>();
        map.put("VARCHAR", "String");
        map.put("INTEGER", "Integer");
        map.put("FLOAT", "Double");
        map.put("DECIMAL", "Double");
        map.put("TIMESTAMP", "String");
        map.put("CHAR", "String");
        map.put("DATETIME", "String");
        map.put("DATE", "String");
        map.put("TIMESTAMP_IMPORT", "String");
        map.put("DATETIME_IMPORT", "String");
        map.put("INT", "Integer");
        map.put("SMALLINT", "Integer");
        map.put("BIGINT", "Integer");
        map.put("DOUBLE", "Double");
        map.put("VARBINARY", "String");

    }

    public static String getPojoType(String dataType)
    {
        StringTokenizer st = new StringTokenizer(dataType);
        return map.get(st.nextToken());
    }

    public static String getImport(String dataType)
    {
        if (map.get(dataType) == null || "".equals(map.get(dataType)))
        {
            return null;
        }
        else
        {
            return map.get(dataType);
        }
    }

    public void tableToBean(Connection connection, String tableName)
            throws SQLException
    {
        String sql = "select * from " + tableName + " where 1 <> 1";
        PreparedStatement ps = null;
        ResultSet rs = null;
        ps = connection.prepareStatement(sql);
        rs = ps.executeQuery();
        ResultSetMetaData md = rs.getMetaData();
        int columnCount = md.getColumnCount();
        StringBuffer sb = new StringBuffer();
        tableName = tableName.substring(0, 1).toUpperCase() + tableName.subSequence(1, tableName.length());
        tableName = this.dealLine(tableName);
        tableName = tableName + "Entity";

        sb.append("package " + this.packages + " ;");
        sb.append(LINE);
        importPackage(md, columnCount, sb);
        sb.append(LINE);
        sb.append(LINE);
        sb.append("public class " + tableName + " implements Serializable");
        sb.append(LINE);
        sb.append("{");
        sb.append(LINE);
        defProperty(md, columnCount, sb);
        genSetGet(md, columnCount, sb);
        sb.append(LINE);
        sb.append("}");
        String paths = System.getProperty("user.dir");
        String endPath = paths + "\\src\\test\\java\\" + (packages.replace("/", "\\")).replace(".", "\\");
        buildJavaFile(endPath + "\\" + tableName + ".java", sb.toString());
    }

    //属性生成get、 set 方法
    private void genSetGet(ResultSetMetaData md, int columnCount, StringBuffer sb)
            throws SQLException
    {
        for (int i = 1; i <= columnCount; i++)
        {
            sb.append(TAB);
            String pojoType = getPojoType(md.getColumnTypeName(i));
            String columnName = dealLine(md, i);
            String getName = null;
            String setName = null;
            if (columnName.length() > 1)
            {
                getName =
                        "public " + pojoType + " get" + columnName.substring(0, 1).toUpperCase()
                                + columnName.substring(1, columnName.length()) + "() ";
                setName =
                        "public void set" + columnName.substring(0, 1).toUpperCase()
                                + columnName.substring(1, columnName.length()) + "(" + pojoType + " " + columnName + ") ";
            }
            else
            {
                getName = "public get" + columnName.toUpperCase() + "() ";
                setName = "public set" + columnName.toUpperCase() + "(" + pojoType + " " + columnName + ") {";
            }
            sb.append(LINE).append(TAB).append(getName).append(LINE).append(TAB).append("{");
            sb.append(LINE).append(TAB).append(TAB);
            sb.append("return " + columnName + ";");
            sb.append(LINE).append(TAB).append("}");
            sb.append(LINE).append(TAB);

            sb.append(LINE).append(TAB).append(setName).append(LINE).append(TAB).append("{");
            sb.append(LINE).append(TAB).append(TAB);
            sb.append("this." + columnName + " = " + columnName + ";");
            sb.append(LINE).append(TAB).append("}");
            sb.append(LINE);

        }
    }

    //导入属性所需包
    private void importPackage(ResultSetMetaData md, int columnCount, StringBuffer sb)
            throws SQLException
    {
        sb.append("import java.io.Serializable;");
        sb.append(LINE);
        sb.append("import com.isoftstone.disk.mybatis.annotation.Columns;");
        sb.append(LINE);
    }

    //属性定义
    private void defProperty(ResultSetMetaData md, int columnCount, StringBuffer sb)
            throws SQLException
    {

        for (int i = 1; i <= columnCount; i++)
        {
            sb.append(TAB);
            sb.append("@Columns(\"");
            sb.append(md.getColumnName(i));
            if ("vote_uuid".equals(md.getColumnName(i)))
            {
                System.out.println(md.getColumnName(i) + "  ||||  " + md.getColumnTypeName(i));
            }
            sb.append("\")");
            sb.append(LINE);
            sb.append(TAB);
            String columnName = dealLine(md, i);
            sb.append("private " + getPojoType(md.getColumnTypeName(i)) + " " + columnName + ";");
            sb.append(LINE);
            if (i != columnCount)
            {
                sb.append(LINE);
            }

        }
    }

    private String dealLine(ResultSetMetaData md, int i)
            throws SQLException
    {
        String columnName = md.getColumnName(i);
        columnName = columnName.toLowerCase();
        // 处理下划线情况，把下划线后一位的字母变大写；
        columnName = dealName(columnName);
        return columnName;
    }

    private String dealLine(String tableName)
    {
        // 处理下划线情况，把下划线后一位的字母变大写；
        tableName = dealName(tableName);
        return tableName;
    }

    //下划线后一位字母大写
    private String dealName(String columnName)
    {
        if (columnName.contains("_"))
        {
            StringBuffer names = new StringBuffer();

            String arrayName[] = columnName.split("_");
            names.append(arrayName[0]);
            for (int i = 1; i < arrayName.length; i++)
            {
                String arri = arrayName[i];
                String tmp = arri.substring(0, 1).toUpperCase() + arri.substring(1, arri.length());
                names.append(tmp);
            }
            columnName = names.toString();

        }

        return columnName;
    }

    //生成java文件
    public void buildJavaFile(String filePath, String fileContent)
    {
        try
        {
            File file = new File(filePath);
            File dir = file.getParentFile();
            if (!dir.exists())
            {
                dir.mkdirs();
            }
            FileOutputStream osw = new FileOutputStream(file);
            PrintWriter pw = new PrintWriter(osw);
            pw.println(fileContent);
            pw.close();
            System.out.println(filePath);
        }
        catch (Exception e)
        {
            System.out.println("生成txt文件出错：" + e.getMessage());
        }
    }

    public static void main(String[] args)
            throws SQLException, ClassNotFoundException
    {
        String jdbcString = "jdbc:mysql://127.0.0.1:3306/cldk_data?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC";
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection con = DriverManager.getConnection(jdbcString, "cldk_data", "Huawei_123");
        DatabaseMetaData databaseMetaData = con.getMetaData();
        String[] tableType = {"TABLE"};
        ResultSet rs = databaseMetaData.getTables(null, null, "%", tableType);
        TableToJavaBean d = new TableToJavaBean();
        while (rs.next())
        {
            String tableName = rs.getString(3).toString();
            d.tableToBean(con, tableName);
        }
    }
}

